<!DOCTYPE html>
<!-- 
    棉花叶片疾病识别Web应用 - 前端页面
    
    本页面提供了用户界面，允许用户上传棉花叶片图片并获取AI识别结果。
    主要功能：
    1. 支持点击和拖拽上传图片
    2. 显示图片预览
    3. 发送图片到后端API进行识别
    4. 显示识别结果（健康/患病）及置信度
-->
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>棉花叶片疾病识别web测试</title>
    <!-- 引入Bootstrap框架的CSS，用于页面样式和布局 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
    <!-- 引入Bootstrap图标库 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
    <!-- 尝试加载本地样式，如果失败也不影响功能 -->
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}" onerror="this.onerror=null;this.href=''">
    <!-- 内联样式定义 -->
    <style>
        /* 页面背景和间距 */
        body {
            background-color: #f8f9fa;
            padding-top: 20px;
        }
        /* 主容器样式 - 白色卡片效果 */
        .container {
            max-width: 800px;
            background-color: white;
            border-radius: 10px;
            padding: 30px;
            box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
        }
        /* 页面标题区域样式 */
        .header {
            text-align: center;
            margin-bottom: 30px;
        }
        /* 文件上传区域样式 - 虚线边框 */
        .upload-area {
            border: 2px dashed #ddd;
            border-radius: 10px;
            padding: 30px;
            text-align: center;
            margin-bottom: 20px;
            cursor: pointer;
            transition: all 0.3s;
        }
        /* 上传区域悬停效果 */
        .upload-area:hover {
            border-color: #28a745;
            background-color: #f8f9fa;
        }
        /* 上传图标样式 */
        .upload-icon {
            font-size: 48px;
            color: #6c757d;
            margin-bottom: 15px;
        }
        /* 图片预览区域样式 */
        .preview-image {
            max-width: 100%;
            max-height: 300px;
            margin: 20px 0;
            border-radius: 5px;
        }
        /* 结果卡片样式 - 初始隐藏 */
        .result-card {
            margin-top: 20px;
            display: none;
        }
        /* 加载状态样式 - 初始隐藏 */
        .loading {
            display: none;
            text-align: center;
            margin: 20px 0;
        }
        /* 加载动画样式 */
        .spinner-border {
            width: 3rem;
            height: 3rem;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>棉花叶片疾病识别web测试</h1>
            <p class="text-muted">上传棉花叶片图片，AI将自动识别是否患病</p>
        </div>
        
        <form id="upload-form" enctype="multipart/form-data">
            <div class="upload-area" id="upload-area">
                <div class="upload-icon">
                    <i class="bi bi-cloud-arrow-up"></i>
                </div>
                <h4>点击或拖拽上传图片</h4>
                <p class="text-muted">支持 JPG、JPEG、PNG 格式</p>
                <input type="file" id="file-input" name="file" accept=".jpg,.jpeg,.png" style="display: none;">
            </div>
            <button type="submit" class="btn btn-primary w-100" id="upload-btn" disabled>开始识别</button>
        </form>
        
        <div class="text-center">
            <img id="preview-image" class="preview-image" style="display: none;">
        </div>
        
        <div class="loading" id="loading">
            <div class="spinner-border text-primary" role="status">
                <span class="visually-hidden">加载中...</span>
            </div>
            <p class="mt-2">正在分析图片，请稍候...</p>
        </div>
        
        <div class="result-card" id="result-card">
            <div class="card">
                <div class="card-header" id="result-header">
                    识别结果
                </div>
                <div class="card-body">
                    <h5 class="card-title" id="result-class"></h5>
                    <p class="card-text" id="result-confidence"></p>
                    <div class="progress mb-3">
                        <div class="progress-bar" id="confidence-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
                    </div>
                    <p class="card-text" id="result-description"></p>
                </div>
            </div>
        </div>
    </div>

    <!-- 引入Bootstrap的JavaScript库 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <!-- 尝试加载本地脚本，如果失败也不影响功能，因为主要JS逻辑已内联 -->
    <script src="{{ url_for('static', filename='js/main.js') }}" onerror="this.onerror=null;this.src=''"></script>
    <!-- 主要JavaScript逻辑 -->
    <script>
        // 当DOM完全加载后执行脚本
        document.addEventListener('DOMContentLoaded', function() {
            // 获取页面中的DOM元素
            const uploadArea = document.getElementById('upload-area');     // 上传区域
            const fileInput = document.getElementById('file-input');       // 文件输入框
            const uploadBtn = document.getElementById('upload-btn');       // 上传按钮
            const previewImage = document.getElementById('preview-image'); // 图片预览
            const uploadForm = document.getElementById('upload-form');     // 上传表单
            const loading = document.getElementById('loading');            // 加载状态
            const resultCard = document.getElementById('result-card');     // 结果卡片
            const resultHeader = document.getElementById('result-header'); // 结果标题
            const resultClass = document.getElementById('result-class');   // 分类结果
            const resultConfidence = document.getElementById('result-confidence'); // 置信度文本
            const confidenceBar = document.getElementById('confidence-bar');       // 置信度进度条
            const resultDescription = document.getElementById('result-description'); // 结果描述
            
            // 点击上传区域触发文件选择（隐藏的文件输入框）
            uploadArea.addEventListener('click', function() {
                fileInput.click();  // 触发隐藏的文件输入框的点击事件
            });
            
            // 处理拖拽文件上传功能
            // 当文件拖动到上传区域上方时
            uploadArea.addEventListener('dragover', function(e) {
                e.preventDefault();  // 阻止默认行为
                // 改变上传区域样式，提供视觉反馈
                uploadArea.style.borderColor = '#28a745';  // 绿色边框
                uploadArea.style.backgroundColor = '#f8f9fa';  // 浅灰色背景
            });
            
            // 当文件离开上传区域时
            uploadArea.addEventListener('dragleave', function() {
                // 恢复上传区域默认样式
                uploadArea.style.borderColor = '#ddd';
                uploadArea.style.backgroundColor = '';
            });
            
            // 当文件被放置到上传区域时
            uploadArea.addEventListener('drop', function(e) {
                e.preventDefault();  // 阻止默认行为（在新窗口打开文件）
                // 恢复上传区域默认样式
                uploadArea.style.borderColor = '#ddd';
                uploadArea.style.backgroundColor = '';
                
                // 如果有文件被放置
                if (e.dataTransfer.files.length) {
                    // 将拖放的文件赋值给文件输入框
                    fileInput.files = e.dataTransfer.files;
                    // 处理文件选择
                    handleFileSelect();
                }
            });
            
            // 监听文件选择变化事件
            fileInput.addEventListener('change', handleFileSelect);
            
            /**
             * 处理文件选择
             * 验证文件类型，显示图片预览，并启用上传按钮
             */
            function handleFileSelect() {
                // 检查是否有文件被选择
                if (fileInput.files.length) {
                    const file = fileInput.files[0];  // 获取选择的第一个文件
                    
                    // 检查文件类型是否为允许的图片格式
                    const validTypes = ['image/jpeg', 'image/jpg', 'image/png'];
                    if (!validTypes.includes(file.type)) {
                        // 如果文件类型不符合要求，显示警告并退出函数
                        alert('请上传JPG、JPEG或PNG格式的图片！');
                        return;
                    }
                    
                    // 创建图片预览
                    const reader = new FileReader();  // 创建文件读取器
                    // 当文件读取完成时执行
                    reader.onload = function(e) {
                        // 设置预览图片的源为读取的数据URL
                        previewImage.src = e.target.result;
                        // 显示预览图片
                        previewImage.style.display = 'block';
                    };
                    // 以数据URL形式读取文件（base64编码）
                    reader.readAsDataURL(file);
                    
                    // 启用上传按钮，允许用户提交
                    uploadBtn.disabled = false;
                }
            }
            
            // 监听表单提交事件
            uploadForm.addEventListener('submit', function(e) {
                e.preventDefault();  // 阻止表单默认提交行为
                
                // 验证是否选择了文件
                if (!fileInput.files.length) {
                    alert('请先选择一张图片！');
                    return;
                }
                
                // 显示加载状态，隐藏结果，禁用上传按钮
                loading.style.display = 'block';
                resultCard.style.display = 'none';
                uploadBtn.disabled = true;
                
                // 创建FormData对象用于文件上传
                const formData = new FormData();
                formData.append('file', fileInput.files[0]);  // 添加文件到表单数据
                
                // 发送POST请求到后端API
                fetch('/predict', {
                    method: 'POST',
                    body: formData  // 使用FormData作为请求体
                })
                .then(response => response.json())  // 将响应解析为JSON
                .then(data => {
                    // 处理响应数据
                    
                    // 恢复界面状态
                    loading.style.display = 'none';  // 隐藏加载状态
                    uploadBtn.disabled = false;      // 启用上传按钮
                    
                    // 检查是否有错误
                    if (data.error) {
                        alert('错误: ' + data.error);
                        return;
                    }
                    
                    // 显示结果卡片
                    resultCard.style.display = 'block';
                    
                    // 根据识别结果设置UI元素
                    const isHealthy = data.class.includes('健康');
                    
                    // 设置结果标题样式和文本（健康为绿色，患病为红色）
                    resultHeader.className = isHealthy ? 'card-header bg-success text-white' : 'card-header bg-danger text-white';
                    resultHeader.textContent = isHealthy ? '识别结果: 健康' : '识别结果: 患病';
                    
                    // 设置分类结果和置信度文本
                    resultClass.textContent = data.class;  // 显示分类结果
                    resultConfidence.textContent = `置信度: ${data.confidence}`;  // 显示置信度
                    
                    // 设置置信度进度条
                    const confidenceValue = parseFloat(data.confidence);  // 解析置信度数值
                    confidenceBar.style.width = `${confidenceValue}%`;    // 设置进度条宽度
                    confidenceBar.className = isHealthy ? 'progress-bar bg-success' : 'progress-bar bg-danger';  // 设置进度条颜色
                    confidenceBar.setAttribute('aria-valuenow', confidenceValue);  // 更新ARIA属性
                    
                    // 根据结果设置建议描述文本
                    if (isHealthy) {
                        // 健康叶片的建议
                        resultDescription.textContent = '您的棉花叶片健康状况良好，继续保持当前的种植管理方式。';
                    } else {
                        // 患病叶片的建议
                        resultDescription.textContent = '您的棉花叶片可能患有疾病，建议及时采取防治措施，如喷洒适当的农药或咨询农业专家。';
                    }
                })
                .catch(error => {
                    // 处理请求错误
                    loading.style.display = 'none';  // 隐藏加载状态
                    uploadBtn.disabled = false;      // 启用上传按钮
                    alert('请求出错: ' + error.message);  // 显示错误信息
                });
            });
        });
    </script>
</body>
</html> 